
#include <cstdlib>
#include <iostream>

#include <math.h>

#include "SDL.h"
#include "SDL_opengl.h"

#include "common.h"

#include "Fan.h"

using namespace std;

__BEGIN_NAMESPACE_DECL_

Fan::Fan(int segments, int blades)
    : _segments(segments), _blades(blades)
{ 
    _angleOfRotation = 0;
}

void Fan::draw()
{
    int i;

    // Save current matrix
    glPushMatrix();

    // Apply any translation, rotation or scaling factors set for this object
    transform();

    // Rotate x-axis by 90 degrees.  We draw the object in the x/y planes,
    // so rotating it here will make the object "upright"
    glRotated (-90, 1.0, 0.0, 0.0);

    // Set the color to silver
    glColor3d (0.61, 0.61, 0.61);

    // Draw the tall skinny rod from which the fan hangs from the ceiling
    drawCylinder (0.0,  // x1
                  0.0,  // y1
                  0.2,  // radius
                  0.1,  // zOffset
                  0.4,  // thickness
                  _segments);

    glPushMatrix();
      // Rotate the fan by its current angle of rotation
      glRotated (_angleOfRotation, 0.0, 0.0, 1.0);

      // Draw the short, fat base of the fan
      drawCylinder (0.0,  // x1
                    0.0,  // y1
                    1.0,  // radius
                   -0.1,  // zOffset
                    0.2,  // thickness
                    _segments);

      // Draw the fan blades in brown (wood)
      glColor3d  (0.357, 0.133, 0.0);

      for (i=0; i < _blades; i++)
      {
          glPushMatrix();

          double j = (double)i/(double)_blades;
          double angle = j * 360.0;
          double x = cos(j*2.0*M_PI)/2.0;
          double y = sin(j*2.0*M_PI)/2.0;

          // "Attach" the fan blade to the correct position on the base 
          // by moving it from the origin to the calculated point on the
          // circle
          glTranslated (x, y, 0.0);

          // Rotate the fan blade by the calculated angle.
          // You can think of this as putting the blade perpendicular to the 
          // tangent of the circle that is the base of the fan.
          glRotated (angle, 0.0, 0.0, 1.0);

          // Rotate the fan blade around x-axis to achieve an orientation similar
          // to a typical fan blade that would push air down.
          glRotated (22.5, 1.0, 0.0, 0.0);

          // Draw the fan blade.  We draw it from slightly left of the origin
          // to 1.0 on the positive x-axis.  The reason we draw it slightly left
          // is so that the end of the blade intersects with the base and 
          // therefore it looks like the blade goes into the base, as opposed to
          // just touching the base at a single point.
          glBegin(GL_QUADS);

          // top of fan blade
          glNormal3d ( 0.0,  0.0, 1.0);
          glVertex3d (-0.1, -0.1, 0.0);
          glVertex3d ( 1.0, -0.2, 0.0);
          glVertex3d ( 1.0,  0.2, 0.0);
          glVertex3d (-0.1,  0.1, 0.0);

          // bottom of fan blade
          glNormal3d ( 0.0,  0.0, -1.0);
          glVertex3d (-0.1, -0.1, -0.02);
          glVertex3d ( 1.0, -0.2, -0.02);
          glVertex3d ( 1.0,  0.2, -0.02);
          glVertex3d (-0.1,  0.1, -0.02);

          // sides of the fan blade
          glNormal3d ( 0.0, -1.0, 0.0);
          glVertex3d (-0.1, -0.1, 0.0);
          glVertex3d (-0.1, -0.1, -0.02);
          glVertex3d ( 1.0, -0.2, -0.02);
          glVertex3d ( 1.0, -0.2, 0.0);

          glNormal3d ( 1.0,  0.0, 0.0);
          glVertex3d ( 1.0, -0.2, 0.0);
          glVertex3d ( 1.0, -0.2, -0.02);
          glVertex3d ( 1.0,  0.2, -0.02);
          glVertex3d ( 1.0,  0.2, 0.0);

          glNormal3d ( 0.0,  1.0, 0.0);
          glVertex3d ( 1.0,  0.2, 0.0);
          glVertex3d ( 1.0,  0.2, -0.02);
          glVertex3d (-0.1,  0.1, -0.02);
          glVertex3d (-0.1,  0.1, 0.0);

          glNormal3d (-1.0,  0.0, 0.0);
          glVertex3d (-0.1,  0.1, 0.0);
          glVertex3d (-0.1,  0.1, -0.02);
          glVertex3d (-0.1, -0.1, -0.02);
          glVertex3d (-0.1, -0.1, 0.0);

          // Done with fan blade
          glEnd();
          glPopMatrix();
      }
    glPopMatrix();

    // Restore matrix
    glPopMatrix();
}


__END_NAMESPACE_DECL_
